#include <stdarg.h>
#include "datastream.h"

#define DEFAULT_CAPACITY 100

/** create a new DataStream */
DataStream DataStreamNew()
	{
	DataStream buff=(DataStream)malloc(sizeof(DataStreamStructure));
	if(buff==NULL) return NULL;
	
	buff->data=(char*)malloc(DEFAULT_CAPACITY*sizeof(char));
	if(buff->data==NULL)
		{
		free(buff);
		return NULL;
		}
	buff->capacity=DEFAULT_CAPACITY;
	buff->size=0;
	buff->data[0]=0;
	return buff;
	}
/** free a  DataStream */
void DataStreamFree(DataStream buff)
	{
	if(buff==NULL) return ;
	if(buff->data!=NULL) free(buff->data);
	free(buff);
	}

int DataStreamAppend(DataStream buff,const char* s,datastream_size_t length)
	{
	if(buff==NULL || s==NULL || length<0) return 0;
	if(length==0) return 1;
	if(buff->size + length >= buff->capacity)
		{
		int new_capacity= (buff->size + length) + DEFAULT_CAPACITY ; 
		char* array=(char*)realloc(buff->data,new_capacity);
		if(array==NULL)
			{
			return 0;
			}
		buff->data=array;
		buff->capacity = new_capacity;
		}
	memcpy(&buff->data[buff->size],s,length*sizeof(char));
	buff->size+=length;
	return 1;
	}

int DataStreamAppendC(DataStream buff,char c)
	{
	return DataStreamAppend(buff,&c,1);
	}

datastream_size_t DataStreamSize( const DataStream ptr)
	{
	if(ptr==NULL) return -1;
	return ptr->size;
	}

const char* DataStreamData(const DataStream ptr)
	{
	if(ptr==NULL) return NULL;
	return ptr->data;
	}

void DataStreamClear( DataStream ptr)
	{
	if(ptr==NULL) return ;
	ptr->size=0;
	}
	
int DataStreamRead(DataStreamReader in,char* buffer,datastream_size_t length)
	{
	if(	in==NULL  ||
		DataStreamData(in->in)==NULL ||
		in->position<0 || buffer==NULL ||
		length<0
		) return 0;
	if(length==0) return 1;
	if(in->position + length > DataStreamSize(in->in))
		{
		return 0;
		}
	memcpy(buffer,&DataStreamData(in->in)[in->position],sizeof(char)*length);
	in->position+=length;
	return 1;
	}
